package com.hfh.server.netty_server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;

/**
 * @author liuxinghong
 * @Description: nettyserver配置参数
 * @date 2019/9/2 000214:24
 */
@Component
@Slf4j
public class NettyServer {

    private final EventLoopGroup bossGroup = new NioEventLoopGroup(); //用于接收客户端请求的线程池
    private final EventLoopGroup workerGroup = new NioEventLoopGroup(); //用于处理请求数据的线程池

    public static Channel channel =null;
    @Autowired
    NettyServerStringProtocolInitalizer protocolInitalizer;

    /**
     * 启动netty客户端
     */
    @PostConstruct
    public void startServer() {
        ServerBootstrap bootstrap = new ServerBootstrap(); //创建服务器端启动助手
        ChannelFuture channelFuture = null;

        try {
            bootstrap.group(bossGroup, workerGroup)//设置两个线程组
                    .channel(NioServerSocketChannel.class) //选用nio作为通道实现
                    .option(ChannelOption.SO_BACKLOG, NettyConfig.NETTY_SERVER_BACKLOG) //设置线程队列中等待的线程个数
                    .childOption(ChannelOption.SO_KEEPALIVE, NettyConfig.NETTY_SERVER_KEEP_ALIVE) //Socket参数，连接保活，默认值为False。启用该功能时，TCP会主动探测空闲连接的有效性。可以将此功能视为TCP的心跳机制，需要注意的是：默认的心跳间隔是7200s即2小时。Netty默认关闭该功能。
                    .childHandler(protocolInitalizer);
//               .childHandler(new ChannelInitializer<SocketChannel>() {  //初始化通道
//                   @Override
//                   protected void initChannel(SocketChannel socketChannel) throws Exception {
//                       socketChannel.pipeline().addLast(new ServerHandler());//将业务处理handdler加入到channel链中
//                   }
//               });
            channelFuture = bootstrap.bind(NettyConfig.NETTY_SERVER_IP, NettyConfig.NETTY_SERVER_PORT).sync();//绑定ip 端口，非阻塞方式
            channel = channelFuture.channel();
            log.info("netty_server已启动........");
        } catch (InterruptedException e) {
            log.error("netty_server启动失败》》》");
            this.destroy(); //启动失败关闭线程组和通道
            e.printStackTrace();
        } finally {
            if (channelFuture != null && channelFuture.isSuccess()) {
                log.info("netty服务端监听:" + channelFuture.channel() + " ip地址：" + NettyConfig.NETTY_SERVER_IP + " 端口 " + NettyConfig.NETTY_SERVER_PORT + " 正在等待客户端连接中..............");
            }
        }
    }

    /**
     * 销毁/关闭服务器
     */
    public void destroy() {
        log.info("关闭nettyServer");
        try {
            if (channel != null) {
                channel.close().sync(); //异步关闭处理
            }
            workerGroup.shutdownGracefully();
            bossGroup.shutdownGracefully();
            log.info("Shutdown Netty Server Success!");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

}
